#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
#include <minigui/control.h>
#include "lang.h"
#include "resource.h"
#include "mhedit.h"
#include "func.h"
#include "com.h"

/*
 *
 */
void SetEditBorder(HWND hWnd, int border)
{
    int nData = GetWindowAdditionalData(hWnd);
    nData &= 0xFF00FFFF;
    nData |= border;
    SetWindowAdditionalData(hWnd, nData);
}
/*
 * set edit to be active
 */
void SetEditActive(HWND hWnd, BOOL bActive)
{
    int nData = GetWindowAdditionalData(hWnd);
    if(bActive)
    {
        nData |= MH_EDIT_ACTIVE;
    }
    else
    {
        nData &= ~MH_EDIT_ACTIVE;
    }
    SetWindowAdditionalData(hWnd, nData);
}
/*
 * set edit to virtual state
 */
void SetEditVirtual(HWND hWnd, BOOL bVirtual)
{
    int nData = GetWindowAdditionalData(hWnd);
    if(bVirtual)
    {
        nData |= MH_EDIT_VIRTUAL;
    }
    else
    {
        nData &= ~MH_EDIT_VIRTUAL;
    }
    SetWindowAdditionalData(hWnd, nData);
}
/*
 * set text color of edit
 */
void SetEditTextColor(HWND hWnd, int color_bit)
{
    int nData = GetWindowAdditionalData(hWnd);
    nData &= 0xFFFF00FF;
    nData |= color_bit;
    SetWindowAdditionalData(hWnd, nData);
}
/*
 * add edit char
 */
void AddEditChar(HWND hWnd, int ch)
{
    const char *p = GetWindowCaption(hWnd);
    int nData = GetWindowAdditionalData(hWnd);
    char sc[EDIT_MAX_LEN + 1] = {0};
    if(nData & MH_EDIT_VIRTUAL)
    {
        nData &= ~MH_EDIT_VIRTUAL;
        SetWindowAdditionalData(hWnd, nData);
        sc[0] = ch;
        SetWindowCaption(hWnd, sc);
        InvalidateRect(hWnd, 0, TRUE);
    }
    else if(p)
    {
        int len = strlen(p);
        if(len + 1 < sizeof(sc))
        {
            strcat(sc, p);
            char tmp[2] = {0, 0};
            tmp[0] = ch;
            strcat(sc, tmp);
            SetWindowCaption(hWnd, sc);
            InvalidateRect(hWnd, 0, TRUE);
        }
    }
}
/*
 * dec edit char
 */
void DecEditChar(HWND hWnd)
{
    const char *p = GetWindowCaption(hWnd);
    int nData = GetWindowAdditionalData(hWnd);
    if(p)
    {
        if(nData & MH_EDIT_VIRTUAL)
        {
            SetWindowCaption(hWnd, "");
            nData &= ~MH_EDIT_VIRTUAL;
            SetWindowAdditionalData(hWnd, nData);
        }
        else
        {
            int len = strlen(p);
            char *sc = calloc(1, len + 1);
            strcat(sc, p);
            sc[len - 1] = 0;
            SetWindowCaption(hWnd, sc);
            free(sc);
        }
        InvalidateRect(hWnd, 0, TRUE);
    }
}
/*
 *
 */
void SetEditPassword(HWND hWnd, BOOL bPwd)
{
    int nData = GetWindowAdditionalData(hWnd);
    if(bPwd)
    {
        nData |= MH_EDIT_PASSWORD;
    }
    else
    {
        nData &= ~MH_EDIT_PASSWORD;
    }
    SetWindowAdditionalData(hWnd, nData);
}
/*
 *
 */
static int MhEditProc (HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case MSG_ERASEBKGND:
        {
            RECT rect;
            GetClientRect(hWnd, &rect);
            HDC hdc = GetClientDC(hWnd);
            int nWidth = GET_RECT_WIDTH(rect);
            int nHeight = GET_RECT_HEIGHT(rect);
            int nData = GetWindowAdditionalData(hWnd);
            if(nData & MH_EDIT_BKGND_GREY)
            {
                SetBrushColor(hdc, COLOR_HQ_GREY(hdc));
            }
            else if(nData & MH_EDIT_BKGND_BLUE)
            {
                SetBrushColor(hdc, COLOR_HQ_BLUE(hdc));
            }
            else if(nData & MH_EDIT_BKGND_WHITE)
            {
                SetBrushColor(hdc, COLOR_HQ_WHITE(hdc));
            }
            else
            {
                SetBrushColor(hdc, COLOR_HQ_BLACK(hdc));
            }
            if(lParam)
            {
                RECT rct;
                memcpy(&rct, (RECT*)lParam, sizeof(RECT));
                int w = GET_RECT_WIDTH(rct);
                int h = GET_RECT_HEIGHT(rct);
                FillBox(hdc, rct.left, rct.top, w, h);
            }
            else
            {
                FillBox(hdc, rect.left, rect.top, nWidth, nHeight);
            }
            if(nData & MH_EDIT_BORDER_GREY)
            {
                SetPenColor(hdc, COLOR_HQ_GREY(hdc));
                Rectangle(hdc, rect.left, rect.top, rect.right - 1, rect.bottom - 1);
            }
            else if(nData & MH_EDIT_BORDER_BLACK)
            {
                SetPenColor(hdc, COLOR_HQ_BLACK(hdc));
                Rectangle(hdc, rect.left, rect.top, rect.right - 1, rect.bottom - 1);
            }
            ReleaseDC(hdc);
        }
        return 0;
    case MSG_LBUTTONDOWN:
        {
            NotifyParent (hWnd, GetDlgCtrlID(hWnd), EN_CLICKED);
        }
        break;
    case MSG_KILLFOCUS:
        {
            InvalidateRect (hWnd, NULL, TRUE);
        }
        break;
    case MSG_SETFOCUS:
        {
            InvalidateRect (hWnd, NULL, TRUE);
        }
        break;
    case MSG_LBUTTONUP:
        {
        }
        break;
    case MSG_PAINT:
        {
            RECT rect;
            GetClientRect(hWnd, &rect);
            HDC hdc = BeginPaint(hWnd);
            SetBkMode(hdc, BM_TRANSPARENT);
            DWORD nStyle = GetWindowStyle(hWnd);
            uint nFormat = DT_VCENTER | DT_SINGLELINE;
            if(nStyle & BS_CENTER)
            {
                nFormat |= DT_CENTER;
            }
            else
            {
                nFormat |= DT_LEFT;
            }
            int nData = GetWindowAdditionalData(hWnd);
            if(nData & MH_EDIT_ACTIVE)
            {
                SetTextColor(hdc, COLOR_HQ_YELLOW(hdc));
            }
            else if (GetFocusChild(GetParent(hWnd)) == hWnd)
            {
                SetTextColor(hdc, COLOR_HQ_RED(hdc));
            }
            else if(nData & MH_EDIT_TEXT_BLACK)
            {
                SetTextColor(hdc, COLOR_HQ_BLACK(hdc));
            }
            else if(nData & MH_EDIT_TEXT_WHITE)
            {
                SetTextColor(hdc, COLOR_HQ_WHITE(hdc));
            }
            else if(nData & MH_EDIT_TEXT_YELLOW)
            {
                SetTextColor(hdc, COLOR_HQ_YELLOW(hdc));
            }
            else if(nData & MH_EDIT_TEXT_GREEN)
            {
                SetTextColor(hdc, COLOR_green);
            }
            else
            {
                SetTextColor(hdc, COLOR_HQ_CYAN(hdc));
            }
            const char *caption = GetWindowCaption(hWnd);
            rect.left += 2;
            rect.right -= 2;
            if(nData & MH_EDIT_PASSWORD)
            {
                if(strcmp(caption, MW_ERROR_PASSWORD_CAPTION))
                {
                    int len = strlen(caption);
                    char *scMem = calloc(1, len + 1);
                    memset(scMem, '*', len);
                    DrawText(hdc, scMem, -1, &rect, nFormat);
                    free(scMem);
                }
                else
                {
                    SetTextColor(hdc, COLOR_HQ_RED(hdc));
                    DrawText(hdc, caption, -1, &rect, nFormat);
                }
            }
            else
            {
                DrawText(hdc, caption, -1, &rect, nFormat);
            }
            if((nData & MH_EDIT_ACTIVE) && g_edit_index > -2)
            {
                SIZE size;
                if(g_edit_index > -1)
                {
                    GetTextExtent(hdc, caption, g_edit_index, &size);
                }
                else
                {
                    GetTextExtent(hdc, caption, strlen(GetWindowCaption(hWnd)), &size);
                }
                if(nFormat & DT_CENTER)
                {
                }
                else
                {
                    rect.left += size.cx;
                    rect.right = rect.left + 16;
                }
                SetTextColor(hdc, COLOR_HQ_WHITE(hdc));
                DrawText(hdc, "_", -1, &rect, DT_VCENTER | DT_SINGLELINE | DT_LEFT);
            }
            EndPaint(hWnd, hdc);
        }
        break;
    case MSG_CREATE:
        {
        }
        break;
    case MSG_DESTROY:
        {
        }
        break;
    }

    return DefaultControlProc (hWnd, message, wParam, lParam);
}

BOOL RegisterMhEdit (void)
{
    WNDCLASS MyClass;

    MyClass.spClassName = MH_EDIT_NAME;
    MyClass.dwStyle     = WS_NONE;
    MyClass.dwExStyle   = WS_EX_NONE;
    MyClass.hCursor     = GetSystemCursor (IDC_ARROW);
    MyClass.iBkColor    = COLOR_lightwhite;
    MyClass.WinProc     = MhEditProc;

    return RegisterWindowClass (&MyClass);
}

void UnregisterMhEdit (void)
{
    UnregisterWindowClass (MH_EDIT_NAME);
}
